﻿using System;
using System.Net;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;

namespace xbmc_json_async.System
{


    public class XClient
    {
        // TODO: Add connection timeout
        // TODO: Exception handling 



        readonly XSettings mSettings;

        public XClient(XSettings settings)
        {
            mSettings = settings;
        }

        public void GetData(string method, object args, XClientResponseReceived internalCallback, XDataReceived userCallback)
        {
            var requestState = new XRequestState
                                   {
                                       InternalCallback = internalCallback,
                                       UserCallback = userCallback,
                                       JsonRequest = BuildJsonPost(method, args),
                                       Request = (HttpWebRequest) WebRequest.Create(mSettings.XJsonInterfaceAddress),
                                       RequestOperation = method
                                   };

            requestState.Request.Credentials = new NetworkCredential(mSettings.UserName, mSettings.Password);
            requestState.Request.ContentType = "application/json";
            requestState.Request.Method = "POST";
            requestState.Request.BeginGetRequestStream(ResponseStreamReceived, requestState);
        }

        /// <summary>
        /// Gets the image thumbnail.
        /// </summary>
        /// <param name="thumbnailPath">The thumbnail path.</param>
        /// <returns></returns>
        public Stream GetImageThumbnail(string thumbnailPath)
        {
            HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(new Uri( mSettings.XVfsInterfaceAddress + "/" + thumbnailPath));
            request.Credentials = new NetworkCredential(mSettings.UserName, mSettings.Password);

            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();


                return response.GetResponseStream();
            }
            catch (Exception) { throw; }
        }
        static void ResponseStreamReceived(IAsyncResult asyncResult)
        {
            var requestState = (XRequestState)asyncResult.AsyncState;
            var postStream = requestState.Request.EndGetRequestStream(asyncResult);
            byte[] postData = Encoding.UTF8.GetBytes(requestState.JsonRequest);
            postStream.Write(postData, 0, postData.Length);
            postStream.Dispose();
            requestState.Request.BeginGetResponse(ResponseReceived, requestState);
        }

        static void ResponseReceived(IAsyncResult asyncResult)
        {
            var requestState = (XRequestState)asyncResult.AsyncState;
            requestState.Response = requestState.Request.EndGetResponse(asyncResult);
            var responseStream = requestState.Response.GetResponseStream();

            if (responseStream != null)
            {
                var streamReader = new StreamReader(responseStream);
                requestState.ResponseData = streamReader.ReadToEnd();
                responseStream.Dispose();
                streamReader.Dispose();
            }

            requestState.Response.Close();
            requestState.JsonRequest = null;

            if (requestState.InternalCallback != null)
                requestState.InternalCallback(requestState);
        }

        static string BuildJsonPost(string method, object args)
        {
            var jsonPost = new JObject {new JProperty("jsonrpc", "2.0"), new JProperty("method", method)};
            if (args != null)
                jsonPost.Add(new JProperty("params", args));

            // TODO: Is there any value in tracking unique id's? 
            jsonPost.Add(new JProperty("id", 1));

            //{ "jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": [ "playcount", "year" ] }, "id": 1 }
            //"{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": {"fields": ["style\",\r\n      \"mood\",\r\n      \"albumlabel\",\r\n      \"theme\",\r\n      \"albumid\",\r\n      \"artistid\",\r\n      \"type\",\r\n      \"description\"\r\n    ]\r\n  },\r\n  \"id\": 1\r\n}"	string

            return jsonPost.ToString();
        }


    }
}